/**
 * Copyright (c) 2018, wuyy All rights reserved.
 * wuyy 专有/保密源代码,未经许可禁止任何人通过任何渠道使用、修改源代码.
 * QQ:16349023
 * 项目名称 : com.wy2.eclipse.tool.logger
 * @version V1.0
 */
package com.wy2.eclipse.tool.logger;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;
import org.slf4j.helpers.SubstituteLoggerFactory;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;

/**
 * @author wuyy<16349023@qq.com>
 * @date 2018年1月29日上午11:48:39
 * 
 */
public class LoggerInitJob extends WorkspaceJob {
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(LoggerInitJob.class);
    
    private final BundleContext bundleContext;
    
    private AtomicBoolean configured= new AtomicBoolean(false);

    /** 
     * Creates a new instance of LoggerInitJob. 
     * @param name
     */
    public LoggerInitJob(String name,BundleContext bundleContext) {
        super(name);
        this.bundleContext=bundleContext;
    }

    /** 
     * @param monitor
     * @return
     * @throws CoreException 
     * @see org.eclipse.core.resources.WorkspaceJob#runInWorkspace(org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
        monitor.setCanceled(true);
        copyLogConfig();
        return Status.OK_STATUS;
    }

    private void copyLogConfig() {
        if(configured.compareAndSet(false, true)) {
            try {
                //File stateDir = getStateLocation().toFile();
                File stateDir=new File(LogActivator.getDefault().getConfigPath(), "log");

                File configFile = new File(stateDir, "logback." + bundleContext.getBundle().getVersion().toString() + ".xml"); //$NON-NLS-1$  //$NON-NLS-2$
                LogActivator.systemOut("Logback config file: " + configFile.getAbsolutePath()); //$NON-NLS-1$
                logger.info("Logback config file: " + configFile.getAbsolutePath());

                if(!configFile.isFile()) {
                  // Copy the default config file to the actual config file
                  InputStream is = bundleContext.getBundle().getEntry("logbackconfiguration/logback.xml").openStream(); //$NON-NLS-1$
                  try {
                    configFile.getParentFile().mkdirs();
                    FileOutputStream fos = new FileOutputStream(configFile);
                    try {
                      for(byte[] buffer = new byte[1024 * 4];;) {
                        int n = is.read(buffer);
                        if(n < 0) {
                          break;
                        }
                        fos.write(buffer, 0, n);
                      }
                    } finally {
                      fos.close();
                    }
                  } finally {
                    is.close();
                  }
                }

                if(System.getProperty(LogActivator.PLUGIN_LOG_DIR, "").length() <= 0) { //$NON-NLS-1$
                  System.setProperty(LogActivator.PLUGIN_LOG_DIR, stateDir.getAbsolutePath());
                }
                if(System.getProperty(LogActivator.PLUGIN_LOG_NAME, "").length() <= 0) { //$NON-NLS-1$
                      System.setProperty(LogActivator.PLUGIN_LOG_NAME, "wy2ToolSuite");
                    }
                loadConfiguration(configFile);


              } catch(Exception e) {
                configured.set(false);
                e.printStackTrace();
                LogActivator.getDefault().getLog().log(new Status(IStatus.WARNING, LogActivator.PLUGIN_ID, "Exception while setting up logging:" + e.getMessage(), e)); //$NON-NLS-1$
                return;
              }
            
            if(!configured.get()) {
                copyLogConfig();
            }
        }
    }
    
    public void loadConfiguration(File configFile) throws JoranException {
        ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
        int i = 0;
        while(loggerFactory instanceof SubstituteLoggerFactory && i < 100) {
          // slf4j is initialization phase
           LogActivator.systemOut("SLF4J logger factory class: " + loggerFactory.getClass().getName()); //$NON-NLS-1$
          try {
            Thread.sleep(50);
          } catch(InterruptedException e) {
            e.printStackTrace();
          }
          i++ ;
          loggerFactory = LoggerFactory.getILoggerFactory();
        }
        if(!(loggerFactory instanceof LoggerContext)) {
          if(loggerFactory == null) {
            // Is it possible?
              LogActivator.systemErr("SLF4J logger factory is null"); //$NON-NLS-1$
            return;
          }
          LogActivator.systemErr("SLF4J logger factory is not an instance of LoggerContext: " //$NON-NLS-1$
              + loggerFactory.getClass().getName());
          return;
        }

        logger.info("Initializing logback");
        LogActivator.systemOut("Initializing logback"); //$NON-NLS-1$
        LoggerContext lc = (LoggerContext) loggerFactory;
        lc.reset();

        JoranConfigurator configurator = new JoranConfigurator();
        configurator.setContext(lc);
        configurator.doConfigure(configFile);
        
        //lc.getl
        
        Logger logger=lc.getLogger("root");// (Logger) LoggerFactory.getLogger(GswwPluginActivator.class);
//      EclipseLogAppender eclipseLogAppender = new EclipseLogAppender();
//      eclipseLogAppender.start();
//      logger.addAppender(eclipseLogAppender);
        ToolSuiteConsoleAppender jdpAppender = new ToolSuiteConsoleAppender();
        jdpAppender.start();
        logger.addAppender(jdpAppender);
        
        //configurator.do

        StatusPrinter.printInCaseOfErrorsOrWarnings(lc);

        LogbackHelper.logJavaProperties(LoggerFactory.getLogger(LogActivator.class));
      }
}
